package com.woniuxy.boot.gateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.boot.common.pojo.ResponseResult;
import com.woniuxy.boot.gateway.feign.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@Component
@Order(-1)
public class AuthGlobalFilter implements GlobalFilter {
    @Autowired
    @Lazy
    private UserService userService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String url = exchange.getRequest().getPath().value();
        System.out.println("请求路径:{" + url+"}");

        if (url.endsWith("/app/user/getCaptcha")
         || url.endsWith("/app/user/loginByPhone")
         || url.endsWith("/pc/admin/loginByAccount")
        ) {
            return chain.filter(exchange);
        } else {
            List<String> tokens = exchange.getRequest().getHeaders().get("token");
            if (tokens == null || tokens.isEmpty()) {
                return getVoidMono(exchange, 603, "no token");
            }
            String token = tokens.getFirst();
            FutureTask<ResponseResult<Void>> futureTask=new FutureTask<>(()->userService.verifyJwt(token));
            new Thread(futureTask).start();
            try {
                ResponseResult<Void> result = futureTask.get();
                if(result.getCode()==200){
                    System.out.println(result);
                    return chain.filter(exchange);
                }
               return getVoidMono(exchange, 604, "invalid token");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private Mono<Void> getVoidMono(ServerWebExchange exchange, int code, String message) {
        ServerHttpResponse response = exchange.getResponse();
        ResponseResult<Void> responseResult = new ResponseResult<>(code, message);
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] datas = new byte[0];
        try {
            datas = objectMapper.writeValueAsString(responseResult).getBytes(StandardCharsets.UTF_8);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        DataBuffer buffer = response.bufferFactory().wrap(datas);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}